#!/bin/bash

# YxYWeb Docker镜像构建脚本
# 作者: YxYWeb Team
# 版本: 1.0.0

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 配置变量
IMAGE_NAME="yxyweb"
IMAGE_TAG="latest"
BUILD_CONTEXT="."
DOCKERFILE="Dockerfile.production"
OUTPUT_FILE="yxyweb-image.tar.gz"
USE_TSINGHUA=false

# 打印带颜色的消息
print_message() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

print_step() {
    echo -e "${BLUE}[STEP]${NC} $1"
}

# 检查Docker是否安装
check_docker() {
    print_step "检查Docker环境..."
    if ! command -v docker &> /dev/null; then
        print_error "Docker未安装，请先安装Docker"
        exit 1
    fi
    
    if ! docker info &> /dev/null; then
        print_error "Docker服务未启动，请启动Docker服务"
        exit 1
    fi
    
    print_message "Docker环境检查通过"
}

# 检查必要文件
check_files() {
    print_step "检查必要文件..."
    
    local required_files=(
        "Dockerfile.production"
        "requirements.txt"
        "startup.py"
        "api/main.py"
        "config/settings.py"
    )
    
    for file in "${required_files[@]}"; do
        if [[ ! -f "$file" ]]; then
            print_error "缺少必要文件: $file"
            exit 1
        fi
    done
    
    print_message "所有必要文件检查通过"
}

# 清理旧镜像
cleanup_old_images() {
    print_step "清理旧镜像..."
    
    # 删除旧的镜像文件
    if [[ -f "$OUTPUT_FILE" ]]; then
        rm -f "$OUTPUT_FILE"
        print_message "已删除旧的镜像文件: $OUTPUT_FILE"
    fi
    
    # 删除旧的Docker镜像
    if docker images | grep -q "$IMAGE_NAME"; then
        docker rmi "$IMAGE_NAME:$IMAGE_TAG" 2>/dev/null || true
        print_message "已删除旧的Docker镜像"
    fi
}

# 构建镜像
build_image() {
    print_step "开始构建Docker镜像..."
    
    local full_image_name="$IMAGE_NAME:$IMAGE_TAG"
    
    print_message "构建镜像: $full_image_name"
    print_message "使用Dockerfile: $DOCKERFILE"
    
    # 构建Docker构建参数
    local build_args=""
    if [[ "$USE_TSINGHUA" == "true" ]]; then
        build_args="--build-arg USE_TSINGHUA=true"
        print_message "使用清华源下载依赖"
    fi
    
    if docker build $build_args -f "$DOCKERFILE" -t "$full_image_name" "$BUILD_CONTEXT"; then
        print_message "镜像构建成功: $full_image_name"
    else
        print_error "镜像构建失败"
        exit 1
    fi
}

# 测试镜像
test_image() {
    print_step "测试镜像..."
    
    local test_container_name="yxyweb-test-$(date +%s)"
    
    print_message "启动测试容器: $test_container_name"
    
    # 启动测试容器（不设置数据库环境变量，使用默认配置）
    docker run -d \
        --name "$test_container_name" \
        -p 8001:8000 \
        "$IMAGE_NAME:$IMAGE_TAG" &
    
    # 等待容器启动
    sleep 10
    
    # 检查容器状态
    if docker ps | grep -q "$test_container_name"; then
        print_message "测试容器启动成功"
        
        # 等待应用启动（给足够时间让应用启动，即使数据库连接失败）
        print_message "等待应用启动..."
        sleep 30
        
        # 检查容器是否仍在运行
        if docker ps | grep -q "$test_container_name"; then
            print_message "容器运行正常"
            
            # 检查应用是否响应（即使数据库连接失败，应用也应该能启动）
            if curl -f http://localhost:8001/health &>/dev/null; then
                print_message "应用健康检查通过"
            else
                print_warning "应用健康检查失败，但容器运行正常"
                print_warning "这可能是正常的，因为测试环境没有配置数据库"
            fi
        else
            print_error "容器启动后异常退出"
            docker logs "$test_container_name" 2>/dev/null || true
        fi
        
        # 停止并删除测试容器
        docker stop "$test_container_name" 2>/dev/null || true
        docker rm "$test_container_name" 2>/dev/null || true
        print_message "测试容器已清理"
    else
        print_error "测试容器启动失败"
        docker logs "$test_container_name" 2>/dev/null || true
        docker stop "$test_container_name" 2>/dev/null || true
        docker rm "$test_container_name" 2>/dev/null || true
        exit 1
    fi
}

# 导出镜像
export_image() {
    print_step "导出镜像..."
    
    print_message "导出镜像到文件: $OUTPUT_FILE"
    
    if docker save "$IMAGE_NAME:$IMAGE_TAG" | gzip > "$OUTPUT_FILE"; then
        local file_size=$(du -h "$OUTPUT_FILE" | cut -f1)
        print_message "镜像导出成功: $OUTPUT_FILE (大小: $file_size)"
    else
        print_error "镜像导出失败"
        exit 1
    fi
}

# 生成部署文档
generate_deployment_docs() {
    print_step "生成部署文档..."
    
    cat > "DEPLOYMENT_GUIDE.md" << EOF
# YxYWeb Docker部署指南

## 镜像信息
- 镜像名称: $IMAGE_NAME:$IMAGE_TAG
- 导出文件: $OUTPUT_FILE
- 构建时间: $(date)

## 快速部署

### 1. 导入镜像
\`\`\`bash
# 导入镜像
docker load < $OUTPUT_FILE

# 验证镜像
docker images | grep $IMAGE_NAME
\`\`\`

### 2. 创建环境配置文件
创建 \`.env\` 文件：
\`\`\`bash
# 数据库配置
DB_USER=your_db_user
DB_PASSWORD=your_db_password
DB_HOST=your_db_host
DB_PORT=3306
DB_NAME=YxY

# AI配置
AI_PROVIDER=openai
AI_AUTH_URL=http://172.16.21.142:7861/token
AI_CHAT_URL=http://116.142.76.181:20025/v1/chat/completions
AI_USERNAME=dxd
AI_PASSWORD=123
AI_MODEL_NAME=deepseek-llm-32B-chat

# 应用配置
DEBUG=false
\`\`\`

### 3. 启动应用
\`\`\`bash
# 使用docker-compose启动
docker-compose -f docker-compose.production.yml up -d

# 或者直接使用docker命令
docker run -d \\
  --name yxyweb-app \\
  -p 8000:8000 \\
  --env-file .env \\
  --restart unless-stopped \\
  $IMAGE_NAME:$IMAGE_TAG
\`\`\`

### 4. 验证部署
\`\`\`bash
# 检查容器状态
docker ps | grep yxyweb

# 检查应用健康状态
curl http://localhost:8000/health

# 查看日志
docker logs yxyweb-app
\`\`\`

## 常用命令

### 停止应用
\`\`\`bash
docker-compose -f docker-compose.production.yml down
\`\`\`

### 重启应用
\`\`\`bash
docker-compose -f docker-compose.production.yml restart
\`\`\`

### 查看日志
\`\`\`bash
docker logs -f yxyweb-app
\`\`\`

### 进入容器
\`\`\`bash
docker exec -it yxyweb-app bash
\`\`\`

## 注意事项

1. 确保数据库服务可访问
2. 确保AI服务配置正确
3. 应用默认端口为8000，请确保端口未被占用
4. 建议使用外部数据库，避免数据丢失

## 故障排除

### 容器启动失败
\`\`\`bash
# 查看详细日志
docker logs yxyweb-app

# 检查环境变量
docker exec yxyweb-app env | grep DB_
\`\`\`

### 数据库连接失败
- 检查数据库配置是否正确
- 确保数据库服务可访问
- 检查防火墙设置

### AI服务连接失败
- 检查AI服务配置
- 确保网络连接正常
- 验证API密钥和URL

## 技术支持

如有问题，请联系技术支持团队。
EOF

    print_message "部署文档已生成: DEPLOYMENT_GUIDE.md"
}

# 主函数
main() {
    echo "=========================================="
    echo "    YxYWeb Docker镜像构建工具"
    echo "=========================================="
    echo ""
    
    # 检查参数
    if [[ "$1" == "--help" || "$1" == "-h" ]]; then
        echo "用法: $0 [选项]"
        echo ""
        echo "选项:"
        echo "  --help, -h        显示帮助信息"
        echo "  --no-test         跳过镜像测试"
        echo "  --tag TAG         指定镜像标签 (默认: latest)"
        echo "  --use-tsinghua    使用清华源下载Python依赖"
        echo ""
        exit 0
    fi
    
    # 解析参数
    SKIP_TEST=false
    while [[ $# -gt 0 ]]; do
        case $1 in
            --no-test)
                SKIP_TEST=true
                shift
                ;;
            --tag)
                IMAGE_TAG="$2"
                shift 2
                ;;
            --use-tsinghua)
                USE_TSINGHUA=true
                shift
                ;;
            *)
                print_error "未知参数: $1"
                exit 1
                ;;
        esac
    done
    
    # 执行构建流程
    check_docker
    check_files
    cleanup_old_images
    build_image
    
    if [[ "$SKIP_TEST" == "false" ]]; then
        test_image
    else
        print_warning "跳过镜像测试"
    fi
    
    export_image
    generate_deployment_docs
    
    echo ""
    echo "=========================================="
    print_message "镜像构建完成！"
    echo "=========================================="
    echo ""
    print_message "镜像文件: $OUTPUT_FILE"
    print_message "部署文档: DEPLOYMENT_GUIDE.md"
    echo ""
    print_message "下一步操作："
    print_message "1. 将 $OUTPUT_FILE 传输到目标服务器"
    print_message "2. 按照 DEPLOYMENT_GUIDE.md 进行部署"
    echo ""
}

# 执行主函数
main "$@" 